<?php

class AchievementMissionService extends AbstractService
{
    /**
     * @var AchievementMissionService
     */
    private static $instance;

    /**
     * Get the instance of AchievementMissionService.
     *
     * @return AchievementMissionService
     */
    public static function get()
    {
        if (!self::$instance) {
            self::$instance = new AchievementMissionService();
        }
        return self::$instance;
    }

    /**
     * Construction.
     */
    protected function __construct()
    {
        parent::__construct();
    }

    /**
     * 玩家创建时触发的逻辑
     *
     * @param int $userId
     * @return void
     */
    public function handleCreate($userId)
    {
        // do nothing
    }

    /**
     * 玩家登录时触发逻辑
     *
     * @param int $userId
     * @return void
     */
    public function handleLogin($userId)
    {
        $reqTime = GameService::get()->getReqTime();

        // 根据条件，判断是否需要初始化成就任务
        AchievementMissionService::get()->createAchievement($userId, $reqTime);
    }

    /**
     * 提供当前 service 数据
     *
     * @param int $userId
     * @param boolean $visitMode default false
     * @return array(CocMissionArray, CocMemberVoList)
     */
    public function info($userId, $visitMode = false)
    {
        return array();
    }

    /**
     * 遍历任务列表，接取成就任务
     *
     * @param int $userId
     * @param int $reqTime
     * @return void
     */
    public function createAchievement($userId, $reqTime)
    {
        $missionList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_MISSION);
        if ($missionList->getListCount() > 0) {
            return;
        }

        // 没有任务列表，自动创建成就任务，成就任务类型：98
        $taskSettings = SzConfig::get()->loadAppConfig(GameConst::CONFIG_TASK, null, true);
        foreach ($taskSettings as $taskId => $taskSetting) {
            if ($taskSetting['taskType'] == GameConst::MISSION_TYPE_ACHIEVEMENT && $taskSetting['preTask'] == -1) {
                $initVal = $this->specialValHandle($userId, $taskId);
                MissionService::get()->accept($userId, $taskId, $reqTime, $reqTime, GameConst::SQL_INT_LIMITED, $initVal);
            }
        }
    }

    /**
     * 对某些任务初始值的特殊处理
     * @param $userId
     * @param $taskId
     * @return int
     */
    private function specialValHandle($userId, $taskId)
    {
        switch ($taskId) {
            case GameConst::SPECIAL_MISSION_LEVEL:
                return UserService::get()->getUserLevel($userId);
                break;
            default:
                return 0;
        }
    }

    /**
     * 完成成就任务，并下发后置成就任务
     *
     * @param int $userId
     * @param int $missionId
     * @param int $reqTime
     * @throws SzException
     * @return array($missionList, $missionId)
     */
    public function finishAchievement($userId, $missionId, $reqTime)
    {
        $taskSetting = SzConfig::get()->loadAppConfig(GameConst::CONFIG_TASK, $missionId, true);
        $achievementBonusSettings = SzConfig::get()->loadAppConfig(GameConst::CONFIG_TASK_ACHIEVEMENT_BONUS, null, true);

        // 获取已经完成的成就列表
        $achievementFinished = UserService::get()->getInfo($userId, GameConst::USER_INFO_TYPE_ACHIEVEMENT_FINISHED);
        $achievementFinished = (!$achievementFinished) ? array() : $achievementFinished;
        if (in_array($missionId, $achievementFinished)) {
            throw new SzException(21120);
        }

        /**
         * @var MissionVoList $missionList
         * @var MissionVo $mission
         */
        $missionList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_MISSION);

        // 是否有前置进度
        $clearMissionInfo = ($taskSetting['nextTask'][0] == -1) ? false : true;
        $initialValue = 0;
        if ($clearMissionInfo) {
            $mission = $missionList->getElement($missionId);
            foreach ($mission->getRawConditionsProgress() as $key => $value) {
                $initialValue = $value;
            }
        }

        // 完成成就任务
        MissionService::get()->finish($userId, $missionId, $clearMissionInfo, $initialValue, $missionList);

        // 记录成就任务已经完成
        $achievementFinished[] = $missionId;
        UserService::get()->updateProfileInfo($userId, GameConst::USER_INFO_TYPE_ACHIEVEMENT_FINISHED, $achievementFinished);

        // 发放成就点数
        $achievementScore = UserService::get()->getInfo($userId, GameConst::USER_INFO_TYPE_ACHIEVEMENT_SCORE);
        $achievementScore = (!$achievementScore) ? 0 : $achievementScore;
        $achievementScore += $taskSetting['score'];
        UserService::get()->updateProfileInfo($userId, GameConst::USER_INFO_TYPE_ACHIEVEMENT_SCORE, $achievementScore);

        // 发放成就奖励
        $tid = '';
        $rewardObtained = UserService::get()->getInfo($userId, GameConst::USER_INFO_TYPE_ACHIEVEMENT_REWARD_OBTAINED);
        $rewardObtained = (!$rewardObtained) ? array() : $rewardObtained;
        foreach ($achievementBonusSettings as $key => $bonusInfo) {
            $achievementBonusSetting = $achievementBonusSettings[$key];
            if (in_array($key, $rewardObtained) || $achievementBonusSetting['totalScore'] > $achievementScore) {
                continue;
            }

            foreach ($achievementBonusSetting['bonus'] as $entityId => $count) {
                $tid .= "{$entityId}:{$count}|";
                GameService::get()->handleEntity($userId, $entityId, $count, true, true); //TODO 暂且可以超上限并直接发奖（已确认）
            }

            $rewardObtained[] = $key;
        }
        UserService::get()->updateProfileInfo($userId, GameConst::USER_INFO_TYPE_ACHIEVEMENT_REWARD_OBTAINED, $rewardObtained);

        // 如果 TID 为空，则代表没有领取成就奖励
        if ($tid) {
            // 数据采集：成就奖励领取
            StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_USER_ORBIT, array(
                'clientData' => array(
                    'tid' => 'Module:Achievement|action:claim|',
                    'value' => $missionId
                )
            ));

            // 数据采集：成就奖励产出
            StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_RESOURCE_OUTPUT, array(
                'clientData' => array(
                    'tid' => $tid,
                    'item' => 'Achievement_claim'
                )
            ));
        }

        return array($missionList, $missionId);
    }
}